package com.ljc.aop;

import com.ljc.annotation.ApiLimitedRole;
import com.ljc.auth.UserRole;
import com.ljc.exception.ConditionException;
import com.ljc.interfaces.UserRoleApi;
import com.ljc.support.UserSupport;
import org.apache.dubbo.config.annotation.DubboReference;
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
import org.aspectj.lang.annotation.Pointcut;
import org.springframework.core.annotation.Order;
import org.springframework.stereotype.Component;

import javax.annotation.Resource;
import java.util.Arrays;
import java.util.List;
import java.util.Set;
import java.util.stream.Collectors;

@Order(1)
@Component
@Aspect
public class ApiLimitedRoleAspect {
    @Resource
    private UserSupport userSupport;
    @DubboReference
    private UserRoleApi userRoleApi;

    @Pointcut("@annotation(com.ljc.annotation.ApiLimitedRole)")
    public void check() {
    }

    /**
     * 校验用户是否有权限
     */
    @Before("check() && @annotation(apiLimitedRole)")
    public void doBefore(JoinPoint joinPoint, ApiLimitedRole apiLimitedRole) {
        Long userId = userSupport.getCurrentUserId();
        List<UserRole> userRoleList = userRoleApi.getUserRoleByUserId(userId);
        String[] limitedRoleCodeList = apiLimitedRole.limitedRoleCodeList();
        Set<String> limitedRoleCodeSet = Arrays.stream(limitedRoleCodeList).collect(Collectors.toSet());
        Set<String> roleCodeSet = userRoleList.stream().map(UserRole::getRoleCode).collect(Collectors.toSet());
        // roleCodeSet中剩余的值就是用户的角色编码 和 不允许执行方法的角色编码的交集
        roleCodeSet.retainAll(limitedRoleCodeSet);
        // 如果存在交集，证明没有权限访问方法
        if (!roleCodeSet.isEmpty()) {
            throw new ConditionException("权限不足");
        }
    }
}
